#include <QtOpenGL>
#include "cubo.h"
#include <GL/glut.h>

Cubo::Cubo(const QVector3D& center, QObject *parent):Object3D(center, parent), size(2.0)
{
}

void Cubo::drawGeometry(void)
{
    glBindTexture(GL_TEXTURE_2D, texture());

    if (getSelected()) {
        glutWireCube(size);
    } else {
        glutSolidCube(size);
    }

    glBindTexture(GL_TEXTURE_2D, NULL);
}

float Cubo::intersectionWithLine(QVector3D direction, QVector3D eye)
{
    // http://www.mrl.nyu.edu/~dzorin/rendering/lectures/lecture3/lecture3-6pp.pdf
    QVector3D worldCenter = center() + translation();
    float scaledSize = size*((float) getScaleFactor()/50);
    float scaledSizePer2 = scaledSize/2.0;
    QVector<QVector3D> points(6, *(new QVector3D()));
    points[0].setZ(-scaledSizePer2);
    points[1].setZ(scaledSizePer2);
    points[2].setY(-scaledSizePer2);
    points[3].setY(scaledSizePer2);
    points[4].setX(-scaledSizePer2);
    points[5].setX(scaledSizePer2);
    float tMin = NULL;
    /*
    QVector3D p1(0.0, 0.0, -scaledSize/2.0);
    QVector3D p2(0.0, 0.0, scaledSize/2.0);
    QVector3D p3(0.0, -scaledSize/2.0, 0.0);
    QVector3D p4(0.0, scaledSize/2.0, 0.0);
    QVector3D p5(-scaledSize/2.0, 0.0, 0.0);
    QVector3D p6(scaledSize/2.0, 0.0, 0.0);*/
    //QVector3D p1Normal(0.0, 0.0, -1.0);

    foreach (QVector3D point, points) {
        point = interactiveQuartenion().rotatedVector(point);
        point += worldCenter;

        QVector3D normal = point.normalized();
        float t;
        float directionDotNormal = QVector3D::dotProduct(direction, normal);
        float deltaPDotNormal = QVector3D::dotProduct(point - eye, normal);

        if (deltaPDotNormal == 0 && directionDotNormal == 0 && (tMin == NULL || 0 < tMin)) {
            tMin = 0;
        } else if (directionDotNormal != 0) {
            t = deltaPDotNormal / directionDotNormal;
            QVector3D q = eye + direction*t;
            bool test = insideFace(point, q, scaledSizePer2);
            if (test && (tMin == NULL || t < tMin)) {
                tMin = t;
            }
        }
    }

    return tMin;
}

bool Cubo::insideFace(QVector3D point, QVector3D q, float scaledSizePer2) {
    QVector<QVector3D> vertexs(8, *(new QVector3D(scaledSizePer2,scaledSizePer2,scaledSizePer2)));
    //vertexs[0].setZ(scaledSizePer2);
    vertexs[1].setZ(-scaledSizePer2);
    vertexs[2].setY(-scaledSizePer2);
    vertexs[3].setY(-scaledSizePer2);
    vertexs[3].setZ(-scaledSizePer2);
    vertexs[4].setX(-scaledSizePer2);
    vertexs[5].setX(-scaledSizePer2);
    vertexs[5].setZ(-scaledSizePer2);
    vertexs[6].setX(-scaledSizePer2);
    vertexs[6].setY(-scaledSizePer2);
    vertexs[7].setX(-scaledSizePer2);
    vertexs[7].setY(-scaledSizePer2);
    vertexs[7].setZ(-scaledSizePer2);

    foreach (QVector3D vertex, vertexs) {
        vertex = interactiveQuartenion().rotatedVector(vertex);
    }

    bool  test;

    /*
    QVector3D v1(scaledSizePer2, scaledSizePer2, scaledSizePer2);
    QVector3D v2(scaledSizePer2, scaledSizePer2, -scaledSizePer2);
    QVector3D v3(scaledSizePer2, -scaledSizePer2, scaledSizePer2);
    QVector3D v4(scaledSizePer2, -scaledSizePer2, -scaledSizePer2);
    QVector3D v5(-scaledSizePer2, scaledSizePer2, scaledSizePer2);
    QVector3D v6(-scaledSizePer2, scaledSizePer2, -scaledSizePer2);
    QVector3D v7(-scaledSizePer2, -scaledSizePer2, scaledSizePer2);
    QVector3D v8(-scaledSizePer2, -scaledSizePer2, -scaledSizePer2);
    */

    test = q.x() <= vertexs[0].x() && q.y() <= vertexs[0].y() && q.z() <= vertexs[0].z();
    test = test && q.x() >= vertexs[7].x() && q.y() >= vertexs[7].y() && q.z() >= vertexs[7].z();

    return test;
}
